package main

import (
	"financial_manual_server/comments"
	"financial_manual_server/common"
	"financial_manual_server/util"
	"fmt"
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"regexp"
	"strings"
)

func init() {
	log.SetFlags(log.LstdFlags)
}

func main() {
	config := util.GetConfig()

	log.Println("--------------------------------------------------------------")
	log.Println("Financial Manual Server Version 2023/10/26")
	log.Println("Config load type", config.Server.LoadType)
	log.Println("Listening on port", config.Server.Port)
	log.Println("The access context path is", config.Server.ContextPath)
	log.Println("--------------------------------------------------------------")

	listenOnPort(config)
}

// 安全过滤
func SafeFilter(next http.Handler) http.Handler {
	config := util.GetConfig()
	safePattern := "^" + config.Server.ContextPath + "/_safe/"
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Println(r.Method, r.URL.Path, r.RemoteAddr)
		// 处理跨域
		w.Header().Set("Context-Path", config.Server.ContextPath)
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Add("Access-Control-Allow-Headers", "Content-Type")

		if matched, _ := regexp.MatchString(safePattern, strings.ToLower(r.URL.Path)); matched {
			w.WriteHeader(http.StatusForbidden)
			_, _ = w.Write([]byte("forbidden"))
			return
		}
		// 处理 OPTIONS
		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusOK)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func listenOnPort(config util.Config) {
	r := mux.NewRouter()
	s := r.PathPrefix(config.Server.ContextPath).Subrouter()
	// 评论模块
	s.HandleFunc("/comments/{id:[0-9]+}", comments.ListComment).Methods(http.MethodGet)
	s.HandleFunc("/comments/{id:[0-9]+}", comments.AddComment).Methods(http.MethodPost)
	s.HandleFunc("/comments/{id:[0-9]+}", comments.DeleteComment).Methods(http.MethodDelete)
	s.HandleFunc("/comments/{id:[0-9]+}/agree", comments.Agree).Methods(http.MethodPost)

	// 申请授权接口
	s.HandleFunc("/auth", common.Auth).Methods(http.MethodGet)
	s.HandleFunc("/accessible/{number:[0-9]+}", common.CheckAccessible).Methods(http.MethodGet)
	// 用户头像接口
	s.HandleFunc("/avatar/{uid:[0-9]+}", common.Avatar).Methods(http.MethodGet)

	// 静态资源
	s.PathPrefix("/").Handler(common.StaticAccess(config.Server.ContextPath, "./"))
	// 图标特殊处理，重定向
	r.Path("/favicon.ico").Handler(http.RedirectHandler(config.Server.ContextPath+"/favicon.ico", 308))

	r.Use(mux.CORSMethodMiddleware(r))
	r.Use(SafeFilter)

	err := http.ListenAndServe(fmt.Sprintf(":%d", config.Server.Port), r) //设置监听的端口
	if err != nil {
		log.Fatal("Failed to listen on port", err)
	}
}
